package com.docmgmt.mvp.service;

import com.docmgmt.mvp.ragflow.RAGFlowLLMClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * LLM服务
 * 提供LLM模型查询功能，带缓存优化
 */
@Slf4j
@Service
public class LLMService {

    @Autowired
    private RAGFlowLLMClient llmClient;

    /**
     * 获取当前租户配置的LLM列表（带缓存，30分钟）
     *
     * @return LLM列表
     */
    @Cacheable(value = "llmList", unless = "#result == null || #result.isEmpty()")
    public List<RAGFlowLLMClient.LLMModel> getMyLLMs() {
        try {
            log.info("开始查询RAGFlow LLM列表");
            List<RAGFlowLLMClient.LLMModel> models = llmClient.getMyLLMs();
            log.info("成功查询RAGFlow LLM列表: 共{}个模型", models.size());
            return models;
        } catch (Exception e) {
            log.error("查询RAGFlow LLM列表失败", e);
            throw new RuntimeException("查询LLM列表失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取聊天模型列表（仅返回chat类型的模型）
     *
     * @return 聊天模型列表
     */
    public List<RAGFlowLLMClient.LLMModel> getChatModels() {
        try {
            List<RAGFlowLLMClient.LLMModel> allModels = getMyLLMs();
            return allModels.stream()
                    .filter(model -> "chat".equalsIgnoreCase(model.getModelType()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询聊天模型列表失败", e);
            throw new RuntimeException("查询聊天模型列表失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取嵌入模型列表（仅返回embedding类型的模型）
     *
     * @return 嵌入模型列表
     */
    public List<RAGFlowLLMClient.LLMModel> getEmbeddingModels() {
        try {
            List<RAGFlowLLMClient.LLMModel> allModels = getMyLLMs();
            return allModels.stream()
                    .filter(model -> "embedding".equalsIgnoreCase(model.getModelType()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询嵌入模型列表失败", e);
            throw new RuntimeException("查询嵌入模型列表失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取重排序模型列表（仅返回rerank类型的模型）
     *
     * @return 重排序模型列表
     */
    public List<RAGFlowLLMClient.LLMModel> getRerankModels() {
        try {
            List<RAGFlowLLMClient.LLMModel> allModels = getMyLLMs();
            return allModels.stream()
                    .filter(model -> "rerank".equalsIgnoreCase(model.getModelType()))
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询重排序模型列表失败", e);
            throw new RuntimeException("查询重排序模型列表失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取所有LLM工厂列表（带缓存，1小时）
     *
     * @return LLM工厂列表
     */
    @Cacheable(value = "llmFactoryList", unless = "#result == null || #result.isEmpty()")
    public List<RAGFlowLLMClient.LLMFactory> getFactoryList() {
        try {
            log.info("开始查询RAGFlow LLM工厂列表");
            List<RAGFlowLLMClient.LLMFactory> factories = llmClient.getFactoryList();
            log.info("成功查询RAGFlow LLM工厂列表: 共{}个工厂", factories.size());
            return factories;
        } catch (Exception e) {
            log.error("查询RAGFlow LLM工厂列表失败", e);
            throw new RuntimeException("查询LLM工厂列表失败: " + e.getMessage(), e);
        }
    }

    /**
     * 根据LLM ID查找模型信息
     *
     * @param llmId LLM ID（格式：model_name@factory）
     * @return 模型信息，未找到返回null
     */
    public RAGFlowLLMClient.LLMModel findModelById(String llmId) {
        try {
            String[] parts = RAGFlowLLMClient.parseLLMId(llmId);
            String modelName = parts[0];
            String factory = parts[1];

            List<RAGFlowLLMClient.LLMModel> allModels = getMyLLMs();
            return allModels.stream()
                    .filter(model -> model.getLlmName().equals(modelName)
                            && (factory == null || model.getLlmFactory().equals(factory)))
                    .findFirst()
                    .orElse(null);
        } catch (Exception e) {
            log.error("查找LLM模型失败: llmId={}", llmId, e);
            return null;
        }
    }

    /**
     * 验证LLM ID是否有效（是否在已配置的模型列表中）
     *
     * @param llmId      LLM ID
     * @param modelType  模型类型（可选，如："chat", "embedding"）
     * @return true如果有效
     */
    public boolean validateLLMId(String llmId, String modelType) {
        try {
            RAGFlowLLMClient.LLMModel model = findModelById(llmId);
            if (model == null) {
                return false;
            }
            if (modelType != null && !modelType.isEmpty()) {
                return modelType.equalsIgnoreCase(model.getModelType());
            }
            return true;
        } catch (Exception e) {
            log.error("验证LLM ID失败: llmId={}, modelType={}", llmId, modelType, e);
            return false;
        }
    }
}
